﻿Imports System.ComponentModel

Partial Public Class eComic


    Private Sub eComic_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Closing
        ' if we're closing, then we want to write some things out 
        My.Settings.Save()

        If GetSetting("eComic", "MruList", "FileName1", "").Length > 0 Then
            DeleteSetting("eComic", "MruList")
        End If ' GetSetting("eComic", "MruList", "FileName1", "").Length > 0 
        Dim i As Integer = 0
        Do While i < MRU.Count
            SaveSetting("eComic", "MruList", "FileName" & i + 1, MRU(i).FilePath.ToString)
            i = i + 1
        Loop ' While i < MRU.Count 
    End Sub

    Private Sub eComic_DragEnter(ByVal sender As Object, ByVal e As System.Windows.DragEventArgs) Handles Me.DragEnter
        If e.Data.GetDataPresent(DataFormats.FileDrop) Then
            e.Effects = DragDropEffects.Copy
        Else ' e.Data.GetDataPresent(DataFormats.FileDrop) 
            e.Effects = DragDropEffects.None
        End If ' e.Data.GetDataPresent(DataFormats.FileDrop) 
    End Sub ' eComic_DragEnter 

    Private Sub eComic_Drop(ByVal sender As Object, ByVal e As System.Windows.DragEventArgs) Handles Me.Drop
        Try
            Dim a As Array = CType(e.Data.GetData(DataFormats.FileDrop), Array)
            If Not a Is Nothing Then
                ' Get the string from the first array element (ignoring all files except first if multiple files are dropped)
                Dim fileName As String = a.GetValue(0).ToString
                ' Then we call the Open File as asynchronous format
                '   Explorer instance from which file is dropped is not responding all the time 
                '   when drapDrop handlers are active. Need to return immediate so that the 
                '   Explorer can continue its own processing.
                If IO.File.Exists(fileName) Then FileOpener.RunWorkerAsync(fileName)
                Me.Activate()
            End If
        Catch ex As Exception
            Debug.WriteLine("Error in drapDrop: " & ex.Message)
        End Try
    End Sub ' eComic_Closing 

    Private Sub eComic_Initialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Initialized
        Me.Resources.MergedDictionaries.Add(Microsoft.Windows.Controls.Ribbon.PopularApplicationSkins.Office2007Silver)
        Me.DataContext = Me
        lstPages.ItemsSource = Me.Pages

        FileOpener = New BackgroundWorker
        FileOpener.WorkerReportsProgress = True
        FileOpener.WorkerSupportsCancellation = True

        Dim file_name As String
        For i As Integer = 1 To MRU.MaxCount
            ' Get the next file name and title.
            file_name = GetSetting("eComic", "MruList", "FileName" & i, "")

            ' See if we got anything.
            If file_name.Length > 0 AndAlso IO.File.Exists(file_name) Then
                ' Save this file name.
                MRU.Append(New MostRecentFile(file_name, True))
            End If
        Next i

        Me.mruList.ItemsSource = _mru
        Me.mruList.Items.Refresh()
    End Sub ' eComic_Initialized 

    Private _comic As New Comic
    Private _rl As New readingList
    Private _mru As New MostRecentFiles
    Protected WithEvents FileOpener As BackgroundWorker

    Private Class bw_Out
        Public comic As Comic
        Public rl As readingList
        Public fileName As String
    End Class

    Public Sub LoadFileFromCommandLine(ByVal fileName As String)
        If IO.File.Exists(fileName) Then FileOpener.RunWorkerAsync(fileName)
    End Sub ' LoadFileFromCommandLine 

    Public ReadOnly Property MRU() As MostRecentFiles
        Get
            If _mru Is Nothing Then _mru = New MostRecentFiles
            Return _mru
        End Get
    End Property

    Public ReadOnly Property CurrentPage() As String
        Get
            Return (Me.lstPages.SelectedIndex + 1).ToString
        End Get
    End Property

    Public ReadOnly Property CurrentFileName() As String
        Get
            Dim s As String = ""
            If Not Me.lstPages.SelectedItem Is Nothing Then
                s &= CType(Me.lstPages.SelectedItem, comicPage).FileName
            End If
            Return s
        End Get
    End Property

    Public ReadOnly Property Pages() As ComicPages
        Get
            Return _comic.ComicPages
        End Get
    End Property

    Protected Sub OnOpenCommand(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
        runOpenCommand()
    End Sub ' OnOpenCommand 

    Private Sub runOpenCommand()
        If FileOpener.IsBusy Then FileOpener.CancelAsync()

        Me.Cursor = Cursors.Wait
        Dim f As New Windows.Forms.OpenFileDialog
        f.Multiselect = False
        f.Filter = "All Files (*.*)|*.*|Comic Book Archives (*.cbr, *.cbz, *.cb7, *.rar, *.zip)|*.cbr;*.cbz;*.cb7;*.rar;*.zip|Graphic Novel Archives (*.gnr, *.gnz)|*.gnr;*.gnz|Comic Book PDF (*.pdf)|*.pdf"
        f.FilterIndex = 1
        Dim dlg As Windows.Forms.DialogResult = f.ShowDialog
        If dlg = Forms.DialogResult.OK Then
            If Not _comic Is Nothing Then _comic.Dispose()
            If Not _rl Is Nothing Then _rl.Dispose()

            FileOpener.RunWorkerAsync(f.FileName)
        End If ' dlg = Forms.DialogResult.OK 
    End Sub ' runOpenCommand 

    Protected Sub AppCommandCloseExecuted(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
        If Not _comic Is Nothing Then _comic.Dispose()
        Me.Close()
    End Sub ' AppCommandCloseExecuted 

    Protected Sub ReloadArchive(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
        If Me.FileOpener.IsBusy Then Me.FileOpener.CancelAsync()
        Me.Cursor = Cursors.Wait
        If Not _comic Is Nothing Then _comic.Dispose()
        If Not _rl Is Nothing Then _rl.Dispose()
        FileOpener.RunWorkerAsync(My.Settings.LastFileOpened)
    End Sub ' ReloadArchive 

    Private Sub ResetLastFileOpened(ByVal fn As String)
        Dim ext As String = IO.Path.GetExtension(My.Settings.LastFileOpened)
        Dim ext2 As String = IO.Path.GetExtension(fn)
        If ext.Contains("gn") AndAlso Not ext2.Contains("gn") Then
            ' Do Nothing 
        Else ' ext.Contains("gn") 
            My.Settings.LastFileOpened = fn
        End If ' ext.Contains("gn") 
    End Sub ' ResetLastFileOpened 

    Private Sub PreviousNextArchive_CanExecute(ByVal sender As System.Object, ByVal e As System.Windows.Input.CanExecuteRoutedEventArgs)
        If Me._rl Is Nothing OrElse Me._rl.FileList.Count < 1 Then
            e.CanExecute = False
        Else ' Me._rl Is Nothing 
            e.CanExecute = True
        End If ' Me._rl Is Nothing 
    End Sub 'PreviousNextArchive_CanExecute

    Protected Sub OnNextArchive(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
        gotoOtherArchive(True)
    End Sub ' OnNextArchive 

    Private Sub gotoOtherArchive(ByVal goToNext As Boolean)
        Me.Cursor = Cursors.Wait
        If FileOpener.IsBusy Then FileOpener.CancelAsync()
        Dim fn As String
        If goToNext Then
            If _rl.HasNext Then
                fn = _rl.GetNextFile
            Else ' _rl.HasNext 
                fn = _rl.getFileByIndex(0)
            End If ' _rl.HasNext 
        Else ' goToNext 
            If _rl.HasPrevious Then
                fn = _rl.GetPreviousFile
            Else ' _rl.HasPrevious 
                fn = _rl.getFileByIndex(_rl.FileList.Count - 1)
            End If ' _rl.HasPrevious 
        End If ' goToNext 

        If IO.File.Exists(fn) Then
            ResetLastFileOpened(fn)
            If Not _comic Is Nothing Then _comic.Dispose()
            Me.FileOpener.RunWorkerAsync(fn)
        Else ' IO.File.Exists(fn) 
            MsgBox("Error finding next archive.", MsgBoxStyle.Information, "eComic")
            Me.Cursor = Cursors.Arrow
        End If ' IO.File.Exists(fn) 
    End Sub ' gotoOtherArchive 

    Protected Sub OnPreviousArchive(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
        gotoOtherArchive(False)
    End Sub ' OnPreviousArchive 

    Private Sub comicPage_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
        Me.lblPageName.Content = ""
        Me.lblPageNumber.Content = ""
        Me.imgFull.DataContext = Nothing
        If Not Me.lstPages.SelectedItem Is Nothing AndAlso Me.lstPages.SelectedItem.GetType Is GetType(comicPage) Then
            Dim c As comicPage = Me.lstPages.SelectedItem
            Dim x As New BitmapImage(c.FileNameUri)
            Me.imgFull.Source = x
            Me.lblPageName.Content = Me.CurrentFileName
            Me.lblPageNumber.Content = Me.CurrentPage
        End If ' Not Me.lstPages.SelectedItem Is Nothing  
    End Sub ' comicPage_SelectionChanged 

    Private Sub page_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Input.MouseWheelEventArgs)
        ' Get Current Element 
        Dim i As Integer = Me.lstPages.SelectedIndex
        ' Determine Mouse Direction 
        If e.Delta > 0 Then
            ' Go Back
            If i > 0 Then i -= 1
        Else ' e.Delta > 0 
            ' Go Forward 
            If i < Me.Pages.Count - 1 Then i += 1
        End If ' e.Delta > 0 
        ' Set New current Element 
        Me.lstPages.SelectedIndex = i
        ' Make the UI display item 
        Me.lstPages.ScrollIntoView(Me.lstPages.SelectedItem)
    End Sub ' page_MouseWheel 

    Private Sub GotoPage_CanExecute(ByVal sender As System.Object, ByVal e As System.Windows.Input.CanExecuteRoutedEventArgs)
        If Not Me._comic Is Nothing AndAlso Me._comic.ComicPages.Count > 0 Then
            e.CanExecute = True
        Else ' Not Me._comic Is Nothing 
            e.CanExecute = False
        End If ' Not Me._comic Is Nothing 
    End Sub ' GotoPage_CanExecute 

    Private Sub GotoPage_Executed(ByVal sender As System.Object, ByVal e As System.Windows.Input.ExecutedRoutedEventArgs)
        runGoToPage()
    End Sub ' GotoPage_Executed 

    Protected Sub runGoToPage()
        Dim dlg As New gotoPage
        dlg.Maximum = Me._comic.ComicPages.Count
        dlg.SelectedPage = Me.lstPages.SelectedIndex
        If dlg.ShowDialog Then
            Me.lstPages.SelectedIndex = dlg.SelectedPage
        End If ' dlg.ShowDialog 
    End Sub ' runGoToPage 

    Private Sub FileOpener_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles FileOpener.DoWork
        Try

        
            Dim bw As New bw_Out
            bw.fileName = e.Argument.ToString
            Dim ext As String = IO.Path.GetExtension(bw.fileName)
            If ext.Contains("gn") Then
                bw.rl = New readingList(bw.fileName)
                If FileOpener.CancellationPending Then e.Cancel = True : Exit Sub
                bw.comic = New Comic(_rl.getFileByIndex(0))
                If FileOpener.CancellationPending Then e.Cancel = True : Exit Sub
            Else ' ext.Contains("gn") 
                bw.comic = New Comic(bw.fileName)
                If FileOpener.CancellationPending Then e.Cancel = True : Exit Sub
                bw.rl = New readingList(bw.fileName, True)
                If FileOpener.CancellationPending Then e.Cancel = True : Exit Sub
            End If ' ext.Contains("gn") 

            FileOpener.ReportProgress(1, bw.rl)
            FileOpener.ReportProgress(2, bw.comic)

            Dim fileList As New List(Of String)
            bw.comic.LoadFilesFromSubFolders(bw.comic.TempFolder, fileList)
            fileList.Sort()
            For Each s As String In fileList
                Dim x As New comicPage(s)
                FileOpener.ReportProgress(3, x)
                If FileOpener.CancellationPending Then e.Cancel = True : Exit Sub
            Next ' Each String In fileList 

            e.Result = bw
        Catch ex As Exception
            FileOpener.ReportProgress(-1, ex)
            e.Cancel = True
            e.Result = ex
        End Try
    End Sub ' FileOpener_DoWork 

    Private Sub FileOpener_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles FileOpener.ProgressChanged
        Select Case e.ProgressPercentage
            Case 1 ' Set Reading List 
                Me._rl = e.UserState
            Case 2 ' Set Comic 
                If Not Me._comic Is Nothing Then Me._comic.Dispose()
                Me._comic = e.UserState
                lstPages.ItemsSource = _comic.ComicPages
                lstPages.SelectedIndex = 0
            Case -1
                Dim ex As Exception = e.UserState
                MsgBox("There was an error opening the selected file.", MsgBoxStyle.Critical, "eComic - File Open Error")
                Debug.WriteLine(ex.ToString)
            Case Else
                Me._comic.ComicPages.Add(CType(e.UserState, comicPage))
                lstPages.Items.Refresh()
                If Me._comic.ComicPages.Count = 1 Then lstPages.SelectedIndex = 0
        End Select ' Case e.ProgressPercentage 
    End Sub ' FileOpener_ProgressChanged 

    Private Sub FileOpener_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles FileOpener.RunWorkerCompleted
        Me.Cursor = Cursors.Arrow
        If e.Cancelled Then
            '    If Not e.Result.GetType Is GetType(Exception) Then
            If Not Me._comic Is Nothing Then Me._comic.Dispose() : Me._comic = Nothing
            If Not Me._rl Is Nothing Then Me._rl.Dispose() : Me._rl = Nothing
            MsgBox("Open File Request Was Cancelled.", MsgBoxStyle.Information)
            'End If
        End If ' e.Cancelled 
        Dim bw As bw_Out = e.Result
        My.Settings.LastFileOpened = bw.fileName

        Me.MRU.Append(New MostRecentFile(bw.fileName, True))
        Me.mruList.Items.Refresh()

        Debug.WriteLine("Pages: " & _comic.ComicPages.Count)
        Me.DataContext = Me
        Debug.WriteLine("Pages In Lisbox: " & lstPages.Items.Count)
        '    Me.ZoomControl.Zoom = 0.5
    End Sub

    Private Sub mruList_MostRecentFileSelected(ByVal sender As System.Object, ByVal e As Microsoft.Windows.Controls.Ribbon.MostRecentFileSelectedEventArgs)
        Dim fn As String = CType(e.SelectedItem, MostRecentFile).FilePath
        If Len(Trim(fn)) > 0 AndAlso IO.File.Exists(fn) Then
            If Me.FileOpener.IsBusy Then Me.FileOpener.CancelAsync()
            Me.Cursor = Cursors.Wait
            FileOpener.RunWorkerAsync(fn)
        Else
            MsgBox("The selected file does not exist.", MsgBoxStyle.Information, "eComic")
        End If
    End Sub

    Private Sub eComic_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Input.KeyEventArgs) Handles Me.KeyUp
        If Keyboard.Modifiers = ModifierKeys.Control AndAlso e.Key = Key.G Then
            If Not Me._comic Is Nothing AndAlso Me._comic.ComicPages.Count > 0 Then runGoToPage()
            e.Handled = True
        ElseIf Keyboard.Modifiers = ModifierKeys.Control AndAlso e.Key = Key.Back Then
            gotoOtherArchive(False)
            e.Handled = True
        ElseIf Keyboard.Modifiers = ModifierKeys.Control AndAlso e.Key = Key.Left Then
            gotoOtherArchive(False)
            e.Handled = True
        ElseIf Keyboard.Modifiers = ModifierKeys.Control AndAlso e.Key = Key.Next Then
            gotoOtherArchive(True)
            e.Handled = True
        ElseIf Keyboard.Modifiers = ModifierKeys.Control AndAlso e.Key = Key.Right Then
            gotoOtherArchive(True)
            e.Handled = True
        ElseIf Keyboard.Modifiers = ModifierKeys.Control AndAlso e.Key = Key.O Then
            runOpenCommand()
            e.Handled = True
        End If ' e.Key = Key.G 
    End Sub ' eComic_KeyUp 
End Class
